#include <stdio.h>
#include "./util_lib/util_list.h"
#include "common.h"
#include "_typedef.h"
#include "parse_section.h"


/* 存储TS包的容器【按照pid分类】 */
static TSList_S* pstTSContainer = NULL;

/* 存储观察者 */
static TSList_S* pstObserverCallbackList = NULL;


/* 某一个pid的TS包的存储通道 */
typedef struct TSPackageChl_S
{
    int nPID;
    u16 wCurrSectionLen;
    u16 wSectionLen;
    ParseSectionStatus_E* eParseStatus;
    TSList_S* pstTSlist;
}TSPackageChl_S;

//将TS包组成section
void CSTSSECTIONBuildSection(CSTS_Error_Code* eErrCode, TSPackage_S* pstTSPackage)
{
    int nPID = 0;
    /* 容器迭代器 */
    TSListIterator_S* pstContainerIterator = NULL;
    TSPackageChl_S* pstTSPackageChlTemp = NULL;
    CSTS_BOOL bTSPackageHasChl = CSTS_FALSE;
    TSHeader_S* pstTSHeader = pstTSPackage->pstTSHeader;
    //用于存放 相同PID[上游传递过来]的 通道的List
    TSList_S* pstChlList = NULL;
    //用于存放 通道尾部的包 的临时变量
    TSPackage_S* pstChlTailPackage = NULL;
    //来的TS包要组成的Section的SectionLength
    u16 wNewSectionLen = 0;
    //通道 里面 的List的迭代器
    TSListIterator_S* pstChlListIterator = NULL;
    //SectionBuffer的临时变量
    u8 pu8SectionBufferTmp[1024] = {0};
    u8* pu8SectionBufferTmp1 = NULL;
    int i = 0;

    if(NULL == eErrCode)
    {
        return;
    }

    if(NULL == pstTSPackage || NULL == pstTSHeader)
    {
        *eErrCode = CSTS_ERROR_BAD_PARAMETER;
        return;
    }

    nPID = pstTSHeader->wPID;

    pstContainerIterator = TSCreateListIterator(pstTSContainer);

    while(1)
    {
        if(TSListIteratorHasNext(pstContainerIterator))
        {
            pstTSPackageChlTemp = (TSPackageChl_S*)TSListIteratorNext(pstContainerIterator);
            if(nPID == pstTSPackageChlTemp->nPID)
            {
                bTSPackageHasChl = CSTS_TRUE;
                break;
            }
        }
        else
        {
            break;
        }
    }

    if(!bTSPackageHasChl)
    {
        //丢弃,释放内存
        return;
    }

    pstChlList = pstTSPackageChlTemp->pstTSlist;

    pstChlTailPackage = TSListGetDataTail(pstChlList);

    /* 判断  是否为 一个 合法的TS包 */
    if(1 == pstTSHeader->u8payload_unit_start_indicator)
    {
        if(NULL == pstChlTailPackage)
        {
            TSListInsertDataTail(pstChlList, pstChlTailPackage);
            pstTSPackageChlTemp->wCurrSectionLen += pstChlTailPackage->wTSBufferLen;
            pstTSPackageChlTemp->wSectionLen = 0;
        }
        else
        {
            //丢弃,释放内存
            return;
        }
    }
    else
    {
        if(NULL == pstChlTailPackage)
        {
            //丢弃,释放内存
            return;
        }
        else
        {
            //如果 通道 所对应组Section状态是未知状态或者已完成状态 -- 就丢弃
            if(PARSE_STATUS_INIT_UNKNOW == pstTSPackageChlTemp->eParseStatus
               || PARSE_STATUS_COMPLETE == pstTSPackageChlTemp->eParseStatus)
            {
                //丢弃,释放内存
                return;
            }
            else
            {
                //判断合法性 u8continuity_counter 是否和 上一个连续
                //此处不用管 adapation_field_contorl。因为00 和 10 已经在 第一层被扔掉了
                if(pstTSHeader->u8continuity_counter == (pstChlTailPackage->pstTSHeader->u8continuity_counter + 1) ||
                   (15 == (pstChlTailPackage->pstTSHeader->u8continuity_counter + 1) && 0 == pstTSHeader->u8continuity_counter))
                {
                    //有效数据，插入到链表维护
                    TSListInsertDataTail(pstChlList, pstChlTailPackage);
                    pstTSPackageChlTemp->wCurrSectionLen += pstChlTailPackage->wTSBufferLen;
                }
                else
                {
                    //丢弃,释放内存
                    return;
                }
            }
        }
    }

    /* 判段是否够一个Section */
    //因为第一个包 payload_unit_start_indicator =1 时，可能不含有SECTION_LENGTH字段
    //SECTION_LENGTH占12位，SECTION_LENGTH前面也有12位，SECTION_LENGTH分布在Section第2和第2
    //字节，假设payload_unit_start_indicator =1包的有效数据只有一个字节，就是不满足的
    if(pstTSPackageChlTemp->wSectionLen == 0)
    {
        if(pstTSPackageChlTemp->wCurrSectionLen >= 3)
        {
            //如果 已经获得 的section 长度 >= 3 取出相应数据
            pstChlListIterator = TSCreateListIterator(pstChlList);
            while(1)
            {
                if(TSListIteratorHasNext(pstChlListIterator))
                {
                    pstChlTailPackage = (TSPackage_S*)TSListIteratorNext(pstChlListIterator);
                    memcpy(pu8SectionBufferTmp+i, pstChlTailPackage->pu8TSBuffer, (pstChlTailPackage->wTSBufferLen)*sizeof(u8));
                    i += pstChlTailPackage->wTSBufferLen
                }
                else
                {
                    break;
                }
            }
            wNewSectionLen = (pu8SectionBufferTmp[1] & 0x0F) << 8 | pu8SectionBufferTmp[2];
        }
    }


    if(pstTSPackageChlTemp->wCurrSectionLen < wNewSectionLen)
    {
        //不够一个Section的长度
        pstTSPackageChlTemp->eParseStatus = PARSE_STATUS_NOT_COMPLETE;
        return;
    }

    pstChlListIterator = TSCreateListIterator(pstChlList);
    pu8SectionBufferTmp1 = (u8*)malloc((pstTSPackageChlTemp->wSectionLen)*sizeof(u8));
    i = 0;
    while(1)
    {
        if(TSListIteratorHasNext(pstChlListIterator))
        {
            pstChlTailPackage = (TSPackage_S*)TSListIteratorNext(pstChlListIterator);
            memcpy(pu8SectionBufferTmp1+i, pstChlTailPackage->pu8TSBuffer, (pstChlTailPackage->wTSBufferLen)*sizeof(u8));
            i += pstChlTailPackage->wTSBufferLen
        }
        else
        {
            break;
        }
    }


    return;
    //TS_iSECTIONSendToObservers();
}

//在section的容器注册一个存储通道 -- 加信号量保护
void CSTSSECTIONRegStoreChl(int nNewPID)
{
    /* 新增通道的结构体对象 */
    TSPackageChl_S* psNewtStoreChl = NULL;
    /* 新增通道里面，用于存储的链表对象 */
    TSList_S* pstNewStoreChlList = NULL;

    /*给新增 通道用于存储的链表对象初始化   */
    pstNewStoreChlList = TSCreateList();

    psNewtStoreChl = (TSPackageChl_S*)malloc(sizeof(TSPackageChl_S));
    psNewtStoreChl->nPID = nNewPID;
    psNewtStoreChl->pstTSlist = pstNewStoreChlList;
    psNewtStoreChl->wCurrSectionLen = 0;
    psNewtStoreChl->wSectionLen = 0;
    *(psNewtStoreChl->eParseStatus) = PARSE_STATUS_INIT_UNKNOW;

    /* 将新增通道 放入到容器中 */
    TSListInsertDataTail(pstTSContainer, psNewtStoreChl);
}

//在section的容器移除一个存储通道 -- 加信号量保护
void CSTSSECTIONRemoveStoreChl(int nPID)
{

}

//注册一个观察者
void CSTSSECTIONObserverReg(CSTSSectionSubject_F* fnCSTSSectionSubject_F)
{
    if(NULL == fnCSTSSectionSubject_F)
    {
        printf("the Observer is NULL,parameter error!\n");
        return;
    }
    //将新来的观察者 挂载到  已存在的观察者列表中
    TSListInsertDataTail(pstObserverCallbackList, fnCSTSSectionSubject_F);
}

//移除一个观察者
void CSTSSECTIONObserverRemove(CSTSSectionSubject_F* fnCSTSSectionSubject_F)
{

}


void TS_iSECTIONSendToObservers(u8* pu8SectionBuffer, u16 w16SectionLength, int nPid, int nTableId, void* pUserData)
{
    CSTS_Error_Code eSectionResult = CSTS_ERROR_BAD_PARAMETER;
    TSListIterator_S* pstIterator = NULL;
    CSTSSectionSubject_F* fnTemp = NULL;

    pstIterator = TSCreateListIterator(pstObserverCallbackList);

    while(1)
    {
        //result = TSListIteratorHasNext(s);
        if(TSListIteratorHasNext(pstIterator))
        {
            fnTemp = (CSTSSectionSubject_F*)TSListIteratorNext(pstIterator);
            fnTemp(pu8SectionBuffer, w16SectionLength, nPid, nTableId, &eSectionResult, pUserData);
            if(CSTS_SECTION_USE == eSectionResult)
            {
                break;
            }
        }
        else
        {
            break;
        }
    }
}

//初始化
void CSTSSectionInit()
{
    //创建容器链表
    pstTSContainer = TSCreateList();

    //创建 一个  观察者 的链表
    pstObserverCallbackList = TSCreateList();
}

